package com.hqq.stack.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Stack;

/**
 * Evaluate
 * 使用双栈实现数学表达式的计算
 * Created by heqianqian on 2017/8/3.
 */
public class Evaluate {

    private static final Logger LOGGER = LoggerFactory.getLogger(Evaluate.class);

    public static double calculate(String expression) {
        Stack<String> opStack = new Stack<>();//保存操作符
        Stack<Double> valueStack = new Stack<>();//保存数值
        char[] chars = expression.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            switch (chars[i]) {
                case '('://不做任何操作
                    break;
                case '+':
                case '-':
                case '*':
                case '/':
                    opStack.push(String.valueOf(chars[i]));
                    break;
                case ')'://数值出栈进行算术运算
                    Double value = valueStack.pop();
                    String op = opStack.pop();
                    switch (op) {
                        case "+":
                            value += valueStack.pop();
                            valueStack.push(value);
                            break;
                        case "-":
                            value -= valueStack.pop();
                            valueStack.push(value);
                            break;
                        case "*":
                            value *= valueStack.pop();
                            valueStack.push(value);
                            break;
                        case "/":
                            value /= valueStack.pop();
                            valueStack.push(value);
                            break;
                    }
                    break;
                default://输入的是数值 直接入栈
                    valueStack.push(Double.valueOf(String.valueOf(chars[i])));
                    break;
            }
        }
        return valueStack.pop();
    }

    public static void main(String[] args) {
        String expression = "(1+((2+3)*(4*5)))";
        double calculate = calculate(expression);
        LOGGER.info("Result=" + calculate);
    }

}
